#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>
#include <stdlib.h>
#include <string.h>



/***************************************************************************************
//1.冒泡排序
//
//void print_arr(int arr[], int sz)
//{
//	int i = 0;
//	for (i = 0; i < sz; i++)
//	{
//		printf("%d ", arr[i]);
//	}
//	printf("\n");
//
//}
//
//void bubble_sort(int arr[], int sz)
//{
//	int i = 0;
//	for (i = 0; i < sz - 1; i++)
//	{
//		int j = 0;
//		for (j = 0; j < sz - 1 - i; j++)
//		{
//			if (arr[j] > arr[j + 1])
//			{
//				int temp = arr[j + 1];
//				arr[j + 1] = arr[j];
//				arr[j] = temp;
//			}
//				
//		}
//	}
//}
//
//int main()
//{
//	int arr[10] = { 10,9,8,7,6,5,4,3,2,1 };
//	int sz = sizeof(arr) / sizeof(arr[0]);
//
//	bubble_sort(arr, sz);
//	
//	print_arr(arr, sz);
//	return 0;
//}


****************************************************************************************************************/



//qsort函数，包含在头文件stdlib.h中，直接可以用来排序数据，底层使用快速排序的方法
//qsort函数可以排序任意类型的数据

//funtion qsort
//void qsort (void* base       //指针，指的是，待排序数组的第一个元素
//            size_t num,      //是base指向的数组的元素的个数
//            size_t size      //是base指向的数组的元素的每一个元素的大小，单位是字节
//            int(*compare)(const void*, const void*)) 
            //函数指针，指向的是两个元素的比较函数（回调函数）
            //该函数指针是需要qsort的使用者提供的，qsort函数使用者，需要明确知道排序的元素的数据类型，这是数据是如何比较的
            //把这两个元素的比较方法，封装成函数，然后把函数的地址传递给排序函数



/******************************************************************************************
2.使用qsort函数进行整型类型的排序


int cmp_int(const void* p1, const void* p2)
{
    return (*((int*)p1) - *((int*)p2));
}

print_arr(int arr[], int sz)
{
    int i = 0;
    for (i = 0; i < sz; i++)
    {
        printf("%d ", arr[i]);
    }
    printf("\n");
}

void test()
{
    int arr[10] = { 10,9,8,7,6,5,4,3,2,1 };
    int sz = sizeof(arr) / sizeof(arr[0]);

    qsort(arr, sz, sizeof(arr[0]), cmp_int);
    print_arr(arr, sz);
}


int main()
{
    test();

    return 0;
}


*******************************************************************************************/




/*********************************************************************************************
//3.使用qsort函数对结构体类型进行排序

struct Stu
{
    char name[20];
    int age;
};


int cmp_stu_name(const void* p1, const void* p2)
{
    return strcmp(((struct Stu*)p2)->name, ((struct Stu*)p1)->name);
}

int cmp_stu_age(const void* p1, const void* p2)
{
    return (((struct Stu*)p1)->age - ((struct Stu*)p2)->age);
}

void test()
{
    struct Stu arr[3] = { {"zhangsan",50},{"lisi",25},{"wangwu", 65} };
    int sz = sizeof(arr) / sizeof(arr[0]);
    //qsort(arr, sz, sizeof(arr[0]), cmp_stu_name);
    qsort(arr, sz, sizeof(arr[0]), cmp_stu_age);
}

int main()
{

    test();

    return 0;
}

*****************************************************************************************/





/*********************************************************************************************
//模拟实现qsort函数实现排序整型类型数据

int cmp_int(const void* p1, const void* p2)
{
    return (*((int*)p1) - *((int*)p2));
}

void Swap(char* buf1, char* buf2, size_t width)
{
    int i = 0;
    for (i = 0; i < width; i++)
    {
        char temp = *buf1;
        *buf1 = *buf2;
        *buf2 = temp;
        buf1++;
        buf2++;
    }
}



void bubble_sort(void* base, size_t sz, size_t width, int(*cmp)(const void* p1, const void* p2))
{
    int i = 0;
    for (i = 0; i < sz - 1; i++)
    {
        int j = 0;
        for (j = 0; j < sz - 1 - i; j++)
        {
            //比较arr[j]  和  arr[j + 1]
            if (cmp((char*)base + j * width, (char*)base + (j + 1) * width) > 0)
            {
                Swap((char*)base + j * width, (char*)base + (j + 1) * width, width);
            }
            
         }
    }
}



print_arr(int arr[], int sz)
{
    int i = 0;
    for (i = 0; i < sz; i++)
    {
        printf("%d ", arr[i]);
    }
    printf("\n");
}


void test()
{
    int arr[] = { 10,9,8,7,6,5,4,3,2,1 };
    int sz = sizeof(arr) / sizeof(arr[0]);

    bubble_sort(arr, sz, sizeof(arr[0]), cmp_int);
    print_arr(arr, sz);
}


int main()
{
    test();

    return 0;
}

***************************************************************************************************************/



/*****************************************************************************************************************
//模拟实现qsort函数实现对结构体数据的排序
//其实和上面那个区别就是重新写了一个给qsort函数传的最后一个比较函数cmp_stu_by_name
struct Stu
{
    char name[20];
    int age;
};

int cmp_stu_by_name(const void* p1, const void* p2)
{
    return strcmp(((struct Stu*)p1)->name, ((struct Stu*)p2)->name);
}

int cmp_stu_by_age(const void* p1, const void* p2)
{
    return (((struct Stu*)p1)->age - ((struct Stu*)p2)->age);
}


void Swap(char* buf1, char* buf2, size_t width)
{
    int i = 0;
    for (i = 0; i < width; i++)
    {
        char temp = *buf2;
        *buf2 = *buf1;
        *buf1 = temp;
        buf1++;
        buf2++;
    }
}

void bubble_sort(void* base, size_t sz, size_t width, int(*cmp)(const void* p1, const void* p2))
{
    int i = 0;
    for (i = 0; i < sz - 1; i++)
    {
        int j = 0;
        for (j = 0; j < sz - 1 - i; j++)
        {
            //比较arr[j]和arr[j + 1]
            if (cmp((char*)base + j * width, (char*)base + (j + 1) * width) > 0)
            {
                Swap((char*)base + j * width, (char*)base + (j + 1) * width, width);
            }
        }
    }
}

void test()
{
    struct Stu arr[3] = { {"zhangsan",35},{"lisi",25},{"wangwu",15} };
    int sz = sizeof(arr) / sizeof(arr[0]);

    bubble_sort(arr, sz, sizeof(arr[0]), cmp_stu_by_name);
    bubble_sort(arr, sz, sizeof(arr[0]), cmp_stu_by_age);
}



int main()
{
    test();
    return 0;
}

*********************************************************************************************************************************/